﻿using System.Linq.Expressions;
using SqlSugar;
using FreeRedis;
using Masuit.Tools;
using sixgod.Common;
using sixgod.Model;
using sixgod.Common.Extension;
using sixgod.Common.Model;
using sixgod.Model.System;

namespace Common.ORM.Repository
{
    public class Repository<T> : SimpleClient<T> where T : ModelBase, new()
    {
        private RedisClient _redisClient;

        public Repository(RedisClient redisClient, ISqlSugarClient context) : base(context)
        {
            _redisClient = redisClient;
            base.Context = context;
        }

        public Repository(ISqlSugarClient context):base(context)
        {
            base.Context = context;
        }

        /// <summary>
        /// 获取缓存的数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="query">从缓存中进行数据筛选，而不是从数据库查询条件</param>
        /// <returns></returns>
        public async Task<List<T>> GetListByRedis(string key,Func<T, bool>? query = null)
        {
            var str = await _redisClient.GetAsync(key);
            if (str.IsNullOrEmpty())
            {
                var list = await Context.Queryable<T>().Where(r=>r.IsDelete==0).ToListAsync();
                await _redisClient.SetAsync(key, list.ToJsonString(), 3600 * 24);
                if (query is not null)
                {
                    list = list.Where(query).ToList();
                }
                return list;
            }
            else
            {
                var list = str.ToObj<List<T>>();
                if (query is not null)
                {
                    list = list.Where(query).ToList();
                }
                return list;
            }
        }

        /// <summary>
        /// 获取分页数据
        /// 时间倒序排列
        /// </summary>
        /// <param name="page"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public async Task<PageResponseResult<T>> GetPageList(PageQueryModel page, Expression<Func<T,bool>> exp)
        {
            var pageModel = new PageModel(){ PageSize = page.PageSize,PageIndex = page.PageNum};
            var list = await GetPageListAsync(exp,pageModel,r=>r.UpdateTime,OrderByType.Desc);

            PageResponseResult<T> result = new PageResponseResult<T>();
            result.Count = pageModel.TotalCount;
            result.Data = list;
            return result;
        }

        /// <summary>
        /// 获取分页，默认倒序
        /// </summary>
        /// <param name="page"></param>
        /// <param name="exp"></param>
        /// <param name="orderExp"></param>
        /// <param name="orderByType"></param>
        /// <returns></returns>
        public async Task<PageResponseResult<T>> GetPageList(PageQueryModel page, Expression<Func<T,bool>> exp,Expression<Func<T,object>> orderExp,OrderByType orderByType = OrderByType.Desc)
        {
            var pageModel = new PageModel(){ PageSize = page.PageSize,PageIndex = page.PageNum};
            var list = await GetPageListAsync(exp,pageModel,orderExp,orderByType);

            PageResponseResult<T> result = new PageResponseResult<T>();
            result.Count = pageModel.TotalCount;
            result.Data = list;
            return result;
        }

        /// <summary>
        /// 软删除
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public override Task<bool> DeleteAsync(T data)
        {
            return Context.Updateable<T>().SetColumns("IsDelete",1)
                .SetColumns("UpdateTime",DateTime.Now)
                .Where("Id","=",data.Id)
                .ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 软删除，通过ID进行删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task DeleteByIdAsync(string id)
        {
            return Context.Updateable<T>()
                .SetColumns("IsDelete",1)
                .SetColumns("UpdateTime",DateTime.Now)
                .Where(r=>r.Id == id)
                .ExecuteCommandAsync();
        }
    }
}
